package centerberg.game;

import centerberg.engine.*;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.List;
import java.util.ArrayList;

/**
 * Super class for all menus handling the basic functions
 * such as buttons and basic drawing.
 * 
 * @author Andreas Svanberg
 */
abstract public class Menu
{
    public static final int MENU_WIDTH = 800;
    
    public static final int SCENE_WIDTH = 800;
    public static final int SCENE_HEIGHT = 600;
    
    /**
     * The buttons in this menu.
     */
    protected List<Button> buttons = new ArrayList<Button>();
    
    /**
     * The index of the selectedButton.
     */
    protected int selectedButton;
    
    /**
     * The title of the menu.
     */
    protected String title;
    
    /**
     * Creates a new menu with the given title.
     * 
     * @param title title of the menu
     */
    protected Menu(String title)
    {
        this.title = title;
    }
    
    /**
     * Presses the selected button in this menu.
     */
    public void select()
    {
        buttons.get(selectedButton).pressed();
    }
    
    /**
     * Moves the selection to the next button and redraws
     * the menu. Will wrap around.
     */
    public void next()
    {
        selectedButton = (selectedButton + 1) % buttons.size();
        show();
    }
    
    /**
     * Moves the selection to the previous button and
     * redraws the menu. Will wrap around.
     */
    public void previous()
    {
        selectedButton = (selectedButton - 1 + buttons.size()) % buttons.size();
        show();
    }
    
    /**
     * Draws the buttons on the given graphics and starting
     * at the specified y-coordinate.
     * 
     * @param g the graphics to draw on
     * @param y the y-coordinate to start drawing buttons at
     */
    protected void drawButtons(Graphics2D g, int y)
    {
        g.setFont(g.getFont().deriveFont(Font.BOLD, 18f));
        
        for (Button b : buttons)
        {
            b.draw(g, y, b == buttons.get(selectedButton));
            y += 32;
        }
    }
    
    /**
     * Draws this menu. Since the render only handles
     * scenes and textures we draw the menu on an image
     * and then creating a texture from it. This texture
     * is then added to a scene which is finally rendered.
     */
    public final void show()
    {
        Render render = Engine.getInstance().render;
        Scene menuScene = render.createScene();
        
        BufferedImage img = new BufferedImage(SCENE_WIDTH, SCENE_HEIGHT, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g = img.createGraphics();
        
        g.translate((SCENE_WIDTH - MENU_WIDTH) / 2, 100);
        g.setFont(g.getFont().deriveFont(Font.PLAIN, 28f));
        
        // draw the title in the middle
        int width = g.getFontMetrics().stringWidth(title);
        int x = (MENU_WIDTH - width) / 2;

        g.drawString(title, x, 50);
        int buttonStart = draw(g);
        drawButtons(g, buttonStart);
        
        final Texture menuTexture = new Texture(img, SCENE_WIDTH, SCENE_HEIGHT);
        
        Camera camera = render.getActiveCamera();
        if (camera != null)
            menuTexture.translate(camera.getViewport().x, camera.getViewport().y);
        
        menuScene.add(new Drawable() {
            public Texture getTexture() {
                return menuTexture;
            }
        });
        
        render.render(menuScene);
    }
    
    /**
     * Used by the implementing menus to draw additional
     * information on the menu. Returns an y-coordinate
     * which determines where to begin drawing buttons
     * so that they do not overlap any additional
     * information drawn.
     * 
     * @param g the graphics to draw on
     * @return an y-coordinate where to start drawing
     *         the buttons
     */
    abstract protected int draw(Graphics2D g);
}